﻿using Microsoft.Reporting.WinForms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Windows.Forms;
using TurtleEngine;

namespace Turtle
{
	 /// <summary>
	 /// sql verger: A church officer who takes care of the interior of the building
	 /// and acts as an attendant (carries the verge) during ceremonies.
	 /// </summary>
	 public partial class Turtle : Form
	 {
		  #region "Initialization"

		  /// <summary>
		  /// The entire database
		  /// </summary>
		  private static readonly DataSet entireDatabase = new DataSet("EntireDatabase");

		  /// <summary>
		  /// The object by types to write
		  /// </summary>
		  private static readonly List<string> objectByTypesToWrite =
			 new List<string>(new[] { "Tables", "Views", "Procedures", "Functions", "Triggers", "UserDefinedDataTypes" });

		  /// <summary>
		  /// The server info to write
		  /// </summary>
		  private static readonly List<string> serverInfoToWrite =
			 new List<string>(new[]
								{
									"InstanceInformation", "DataSourceInformation", "DataTypes", "Restrictions", "ReservedWords", "Users",
									"Databases"
								});

		  /// <summary>
		  /// The db connection
		  /// </summary>
		  private static SqlConnection dbConnection;

		  /// <summary>
		  /// The app location
		  /// </summary>
		  private readonly string appLocation;

		  /// <summary>
		  /// The table list
		  /// </summary>
		  private DataSet tableList;

		  /// <summary>
		  /// Initializes a new instance of the <see cref="Turtle" /> class.
		  /// </summary>
		  public Turtle()
		  {
				InitializeComponent();

				appLocation = Assembly.GetExecutingAssembly().Location;
				appLocation = appLocation.Substring(0, appLocation.LastIndexOf("\\"));
		  }

		  /// <summary>
		  /// Gets the DB connection.
		  /// </summary>
		  /// <value>
		  /// The DB connection.
		  /// </value>
		  public static SqlConnection DBConnection
		  {
				get { return dbConnection; }
		  }

		  /// <summary>
		  /// Gets the object by types to write.
		  /// </summary>
		  /// <value>
		  /// The object by types to write.
		  /// </value>
		  public static List<string> ObjectByTypesToWrite
		  {
				get { return objectByTypesToWrite; }
		  }

		  /// <summary>
		  /// Gets the server info to write.
		  /// </summary>
		  /// <value>
		  /// The server info to write.
		  /// </value>
		  public static List<string> ServerInfoToWrite
		  {
				get { return serverInfoToWrite; }
		  }

		  /// <summary>
		  /// Attaches the subreport processing event.
		  /// </summary>
		  /// <param name="reportViewer">The report viewer.</param>
		  private void AttachSubreportProcessingEvent(ReportViewer reportViewer)
		  {
				reportViewer.LocalReport.SubreportProcessing += SubreportProcessingEventHandler;
		  }

		  #endregion "Initialization"

		  #region "Filling Report Tabs"

		  /// <summary>
		  /// Fills all report tab pages.
		  /// </summary>
		  private void FillAllReportTabPages()
		  {
				FillReportTablesMasterDetailView();
				FillReportViewsMasterDetailView();
				FillReportProceduresMasterDetailView();
				FillReportFuntionsMasterDetailView();
				FillReportTriggersMasterDetailView();
				FillReportUDDTsMasterDetailView();
		  }

		  /// <summary>
		  /// Threads the fill all report tab pages.
		  /// </summary>
		  private void ThreadFillAllReportTabPages()
		  {
				ThreadFillReportTablesMasterDetailView();
				ThreadFillReportViewsMasterDetailView();
				ThreadFillReportProceduresMasterDetailView();
				ThreadFillReportFuntionsMasterDetailView();
				ThreadFillReportTriggersMasterDetailView();
				ThreadFillReportUDDTsMasterDetailView();
		  }

		  #region "Tables"

		  /// <summary>
		  /// Fills the report tables hierarchical view.
		  /// </summary>
		  private void FillReportTablesHierarchicalView()
		  {
				FillReport(reportViewerTables, TablesHelper.Tables.Copy(), appLocation + "\\Reports\\TableMap.rdlc", "TableList");
		  }

		  /// <summary>
		  /// Fills the report tables master detail view.
		  /// </summary>
		  private void FillReportTablesMasterDetailView()
		  {
				FillReport(reportViewerTables, TablesHelper.Tables.Copy(), appLocation + "\\Reports\\TableList.rdlc", "TableList");
		  }

		  /// <summary>
		  /// Threads the fill report tables hierarchical view.
		  /// </summary>
		  private void ThreadFillReportTablesHierarchicalView()
		  {
				ThreadFillReport(reportViewerTables, TablesHelper.Tables.Copy(), appLocation + "\\Reports\\TableMap.rdlc", "TableList");
		  }

		  /// <summary>
		  /// Threads the fill report tables master detail view.
		  /// </summary>
		  private void ThreadFillReportTablesMasterDetailView()
		  {
				ThreadFillReport(reportViewerTables, TablesHelper.Tables.Copy(), appLocation + "\\Reports\\TableList.rdlc", "TableList");
		  }

		  #endregion "Tables"

		  #region "Views"

		  /// <summary>
		  /// Fills the report views hierarchical view.
		  /// </summary>
		  private void FillReportViewsHierarchicalView()
		  {
				FillReport(reportViewerViews, ViewsHelper.Views.Copy(), appLocation + "\\Reports\\ViewMap.rdlc", "ViewList");
		  }

		  /// <summary>
		  /// Fills the report views master detail view.
		  /// </summary>
		  private void FillReportViewsMasterDetailView()
		  {
				FillReport(reportViewerViews, ViewsHelper.Views.Copy(), appLocation + "\\Reports\\ViewList.rdlc", "ViewList");
		  }

		  /// <summary>
		  /// Threads the fill report views hierarchical view.
		  /// </summary>
		  private void ThreadFillReportViewsHierarchicalView()
		  {
				ThreadFillReport(reportViewerViews, ViewsHelper.Views.Copy(), appLocation + "\\Reports\\ViewMap.rdlc", "ViewList");
		  }

		  /// <summary>
		  /// Threads the fill report views master detail view.
		  /// </summary>
		  private void ThreadFillReportViewsMasterDetailView()
		  {
				ThreadFillReport(reportViewerViews, ViewsHelper.Views.Copy(), appLocation + "\\Reports\\ViewList.rdlc", "ViewList");
		  }

		  #endregion "Views"

		  #region "Procedures"

		  /// <summary>
		  /// Fills the report procedures hierarchical view.
		  /// </summary>
		  private void FillReportProceduresHierarchicalView()
		  {
				FillReport(reportViewerProcedures, ProceduresHelper.Procedures.Copy(), appLocation + "\\Reports\\ProcedureMap.rdlc",
							"ProcedureList");
		  }

		  /// <summary>
		  /// Fills the report procedures master detail view.
		  /// </summary>
		  private void FillReportProceduresMasterDetailView()
		  {
				FillReport(reportViewerProcedures, ProceduresHelper.Procedures.Copy(), appLocation + "\\Reports\\ProcedureList.rdlc",
							"ProcedureList");
		  }

		  /// <summary>
		  /// Threads the fill report procedures hierarchical view.
		  /// </summary>
		  private void ThreadFillReportProceduresHierarchicalView()
		  {
				ThreadFillReport(reportViewerProcedures, ProceduresHelper.Procedures.Copy(), appLocation + "\\Reports\\ProcedureMap.rdlc",
							"ProcedureList");
		  }

		  /// <summary>
		  /// Threads the fill report procedures master detail view.
		  /// </summary>
		  private void ThreadFillReportProceduresMasterDetailView()
		  {
				ThreadFillReport(reportViewerProcedures, ProceduresHelper.Procedures.Copy(), appLocation + "\\Reports\\ProcedureList.rdlc",
							"ProcedureList");
		  }

		  #endregion "Procedures"

		  #region "Funtions"

		  /// <summary>
		  /// Fills the report functions hierarchical view.
		  /// </summary>
		  private void FillReportFunctionsHierarchicalView()
		  {
				FillReport(reportViewerFunctions, ProceduresHelper.Functions.Copy(), appLocation + "\\Reports\\FunctionMap.rdlc",
							"FunctionList");
		  }

		  /// <summary>
		  /// Fills the report funtions master detail view.
		  /// </summary>
		  private void FillReportFuntionsMasterDetailView()
		  {
				FillReport(reportViewerFunctions, ProceduresHelper.Functions.Copy(), appLocation + "\\Reports\\FunctionList.rdlc",
							"FunctionList");
		  }

		  /// <summary>
		  /// Threads the fill report functions hierarchical view.
		  /// </summary>
		  private void ThreadFillReportFunctionsHierarchicalView()
		  {
				ThreadFillReport(reportViewerFunctions, ProceduresHelper.Functions.Copy(), appLocation + "\\Reports\\FunctionMap.rdlc",
							"FunctionList");
		  }

		  /// <summary>
		  /// Threads the fill report funtions master detail view.
		  /// </summary>
		  private void ThreadFillReportFuntionsMasterDetailView()
		  {
				ThreadFillReport(reportViewerFunctions, ProceduresHelper.Functions.Copy(), appLocation + "\\Reports\\FunctionList.rdlc",
							"FunctionList");
		  }

		  #endregion "Funtions"

		  #region "Triggers"

		  /// <summary>
		  /// Fills the report triggers hierarchical view.
		  /// </summary>
		  private void FillReportTriggersHierarchicalView()
		  {
				FillReport(reportViewerTriggers, SMOHelper.TriggersHelper.Triggers.Copy(), appLocation + "\\Reports\\TriggerMap.rdlc",
							"TriggerList");
		  }

		  /// <summary>
		  /// Fills the report triggers master detail view.
		  /// </summary>
		  private void FillReportTriggersMasterDetailView()
		  {
				FillReport(reportViewerTriggers, SMOHelper.TriggersHelper.Triggers.Copy(),
							appLocation + "\\Reports\\TriggerList.rdlc", "TriggerList");
		  }

		  /// <summary>
		  /// Threads the fill report triggers hierarchical view.
		  /// </summary>
		  private void ThreadFillReportTriggersHierarchicalView()
		  {
				ThreadFillReport(reportViewerTriggers, SMOHelper.TriggersHelper.Triggers.Copy(), appLocation + "\\Reports\\TriggerMap.rdlc",
							"TriggerList");
		  }

		  /// <summary>
		  /// Threads the fill report triggers master detail view.
		  /// </summary>
		  private void ThreadFillReportTriggersMasterDetailView()
		  {
				ThreadFillReport(reportViewerTriggers, SMOHelper.TriggersHelper.Triggers.Copy(),
							appLocation + "\\Reports\\TriggerList.rdlc", "TriggerList");
		  }

		  #endregion "Triggers"

		  #region "UDDTs"

		  /// <summary>
		  /// Fills the report UDD ts hierarchical view.
		  /// </summary>
		  private void FillReportUDDTsHierarchicalView()
		  {
				FillReport(reportViewerUDDTs, SMOHelper.UserDefinedDataTypesHelper.UserDefinedDataTypes.Copy(),
							appLocation + "\\Reports\\UserDefinedDataTypeMap.rdlc", "UserDefinedDataTypeList");
		  }

		  /// <summary>
		  /// Fills the report UDD ts master detail view.
		  /// </summary>
		  private void FillReportUDDTsMasterDetailView()
		  {
				FillReport(reportViewerUDDTs, SMOHelper.UserDefinedDataTypesHelper.UserDefinedDataTypes.Copy(),
							appLocation + "\\Reports\\UserDefinedDataTypeList.rdlc", "UserDefinedDataTypeList");
		  }

		  /// <summary>
		  /// Threads the fill report UDD ts hierarchical view.
		  /// </summary>
		  private void ThreadFillReportUDDTsHierarchicalView()
		  {
				ThreadFillReport(reportViewerUDDTs, SMOHelper.UserDefinedDataTypesHelper.UserDefinedDataTypes.Copy(),
							appLocation + "\\Reports\\UserDefinedDataTypeMap.rdlc", "UserDefinedDataTypeList");
		  }

		  /// <summary>
		  /// Threads the fill report UDD ts master detail view.
		  /// </summary>
		  private void ThreadFillReportUDDTsMasterDetailView()
		  {
				ThreadFillReport(reportViewerUDDTs, SMOHelper.UserDefinedDataTypesHelper.UserDefinedDataTypes.Copy(),
							appLocation + "\\Reports\\UserDefinedDataTypeList.rdlc", "UserDefinedDataTypeList");
		  }

		  #endregion "UDDTs"

		  #region "Helper Methods"

		  /// <summary>
		  /// Fills the report.
		  /// </summary>
		  /// <param name="reportViewer">The report viewer.</param>
		  /// <param name="dt">The dt.</param>
		  /// <param name="reportPath">The report path.</param>
		  /// <param name="datasourceName">Name of the datasource.</param>
		  private void FillReport(ReportViewer reportViewer, DataTable dt, string reportPath, string datasourceName)
		  {
				reportViewer.Reset();
				reportViewer.LocalReport.DataSources.Clear();

				tableList = new DataSet(datasourceName);
				tableList.Tables.Add(dt);

				reportViewer.LocalReport.DisplayName = Path.GetFileNameWithoutExtension(reportPath);
				reportViewer.LocalReport.ReportPath = reportPath;
				reportViewer.LocalReport.SubreportProcessing += SubreportProcessingEventHandler;

				var reportDS = new ReportDataSource();
				reportDS.Name = "SQLDocEngine_Entities_" + datasourceName;
				reportDS.Value = tableList.Tables[0];

				reportViewer.LocalReport.DataSources.Add(reportDS);
				reportViewer.RefreshReport();
		  }

		  /// <summary>
		  /// Threads the fill report.
		  /// </summary>
		  /// <param name="reportViewer">The report viewer.</param>
		  /// <param name="dt">The dt.</param>
		  /// <param name="reportPath">The report path.</param>
		  /// <param name="datasourceName">Name of the datasource.</param>
		  private void ThreadFillReport(ReportViewer reportViewer, DataTable dt, string reportPath, string datasourceName)
		  {
				Invoke(new MethodInvoker(() => reportViewer.Reset()));
				Invoke(new MethodInvoker(() => reportViewer.LocalReport.DataSources.Clear()));

				tableList = new DataSet(datasourceName);
				tableList.Tables.Add(dt);

				Invoke(new MethodInvoker(() => reportViewer.LocalReport.DisplayName = Path.GetFileNameWithoutExtension(reportPath)));
				Invoke(new MethodInvoker(() => reportViewer.LocalReport.ReportPath = reportPath));
				Invoke(new MethodInvoker(() => reportViewer.LocalReport.SubreportProcessing += SubreportProcessingEventHandler));

				var reportDS = new ReportDataSource();
				reportDS.Name = "SQLDocEngine_Entities_" + datasourceName;
				reportDS.Value = tableList.Tables[0];

				Invoke(new MethodInvoker(() => reportViewer.LocalReport.DataSources.Add(reportDS)));
				Invoke(new MethodInvoker(() => reportViewer.RefreshReport()));
		  }

		  #endregion "Helper Methods"

		  #endregion "Filling Report Tabs"

		  #region "Filling Include/Exclude Tabs"

		  /// <summary>
		  /// Fills the combo box.
		  /// </summary>
		  /// <param name="cb">The cb.</param>
		  /// <param name="dt">The dt.</param>
		  /// <param name="nameField">The name field.</param>
		  /// <param name="valueField">The value field.</param>
		  private void FillComboBox(ListBox cb, DataTable dt, string nameField, string valueField)
		  {
				cb.DataSource = dt;
				cb.ValueMember = valueField;
				cb.DisplayMember = nameField;
		  }

		  /// <summary>
		  /// Fills the databases.
		  /// </summary>
		  private void FillDatabases()
		  {
				DatabasesHelper.GetDatabases();
				FillComboBox(ddlDatabase, DatabasesHelper.Databases, "database_name", "dbid");
				RemoveSystemDBS();
		  }

		  /// <summary>
		  /// Fills the function.
		  /// </summary>
		  private void FillFunction()
		  {
				FillListView(listViewFunctions, ProceduresHelper.Functions, "SPECIFIC_NAME");
		  }

		  /// <summary>
		  /// Fills the include exclude objects.
		  /// </summary>
		  private void FillIncludeExcludeObjects()
		  {
				SetStatus("Populating Tables...");
				FillTables();

				SetStatus("Populating Views...");
				FillViews();

				SetStatus("Populating Procedures...");
				FillProcedures();

				SetStatus("Populating Function...");
				FillFunction();

				SetStatus("Populating Triggers...");
				FillTriggers();

				SetStatus("Populating UDDTs...");
				FillUDDTs();
		  }

		  /// <summary>
		  /// Fills the list view.
		  /// </summary>
		  /// <param name="lv">The lv.</param>
		  /// <param name="dt">The dt.</param>
		  /// <param name="name">The name.</param>
		  private void FillListView(ListView lv, DataTable dt, string name)
		  {
				lv.Clear();
				lv.View = View.List;

				foreach (DataRow row in dt.Rows)
				{
					 var item = new ListViewItem(Convert.ToString(row[name]));
					 item.Checked = true;
					 lv.Items.Add(item);
				}
		  }

		  /// <summary>
		  /// Fills the procedures.
		  /// </summary>
		  private void FillProcedures()
		  {
				FillListView(listViewProcedures, ProceduresHelper.Procedures, "SPECIFIC_NAME");
		  }

		  /// <summary>
		  /// Fills the tables.
		  /// </summary>
		  private void FillTables()
		  {
				DataTable tables = TablesHelper.Tables.Copy();
				foreach (DataRow dr in TablesHelper.Tables.Rows)
				{
					 DataRow[] rows = tables.Select("TABLE_TYPE <> 'BASE TABLE'");
					 foreach (DataRow r in rows)
						  r.Delete();
				}
				FillListView(listViewTables, tables, "TABLE_NAME");
		  }

		  /// <summary>
		  /// Fills the triggers.
		  /// </summary>
		  private void FillTriggers()
		  {
				FillListView(listViewTriggers, SMOHelper.TriggersHelper.Triggers, "Name");
		  }

		  /// <summary>
		  /// Fills the UDD ts.
		  /// </summary>
		  private void FillUDDTs()
		  {
				FillListView(listviewUDDT, SMOHelper.UserDefinedDataTypesHelper.UserDefinedDataTypes, "Name");
		  }

		  /// <summary>
		  /// Fills the views.
		  /// </summary>
		  private void FillViews()
		  {
				FillListView(listViewViews, ViewsHelper.Views, "TABLE_NAME");
		  }

		  #endregion "Filling Include/Exclude Tabs"

		  #region "Menu strip click handlers"

		  /// <summary>
		  /// Handles the Click event of the aboutToolStripMenuItem control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
		  {
				var frm = new AboutBox();
				frm.Show();
		  }

		  /// <summary>
		  /// Handles the Click event of the beendenToolStripMenuItem control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void beendenToolStripMenuItem_Click(object sender, EventArgs e)
		  {
				CloseConnection();
				Close();
		  }

		  /// <summary>
		  /// Handles the Click event of the btnAbout control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void btnAbout_Click(object sender, EventArgs e)
		  {
				var frm = new AboutBox();
				frm.Show();
		  }

		  /// <summary>
		  /// Handles the Click event of the btnExit control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void btnExit_Click(object sender, EventArgs e)
		  {
				CloseConnection();
				Close();
		  }

		  /// <summary>
		  /// Handles the CheckedChanged event of the chkIntegratedSecurity control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void chkIntegratedSecurity_CheckedChanged(object sender, EventArgs e)
		  {
				txtUserName.Enabled = !chkIntegratedSecurity.Checked;
				txtUserPassword.Enabled = !chkIntegratedSecurity.Checked;
		  }

		  #endregion "Menu strip click handlers"

		  #region "Connect Button Click Handling"

		  /// <summary>
		  /// Enables the generate UI.
		  /// </summary>
		  /// <param name="state">if set to <c>true</c> [state].</param>
		  public void EnableGenerateUI(bool state)
		  {
				ddlDatabase.Enabled = state;
				btnFetch.Enabled = state;
		  }

		  /// <summary>
		  /// Handles the Click event of the btnConnect control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void btnConnect_Click(object sender, EventArgs e)
		  {
				if (OpenConnection(txtSQLServer.Text, chkIntegratedSecurity.Checked, txtUserName.Text, txtUserPassword.Text, "Master"))
				{
					 btnConnect.Text = "Connected";
					 btnConnect.ForeColor = Color.Green;
					 Utility.DBConnection = dbConnection;
					 EnableGenerateUI(true);
					 FillDatabases();
					 lblMessage.Text = "Select the database from list, and click Fetch button.";
				}
				else
				{
					 btnConnect.Text = "Failed";
					 btnConnect.ForeColor = Color.Red;
					 EnableGenerateUI(false);
				}
				CloseConnection();
		  }

		  #endregion "Connect Button Click Handling"

		  #region "Fetch Button Click Handling"

		  /// <summary>
		  /// Handles the DoWork event of the backgroundWorker1 control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="DoWorkEventArgs" /> instance containing the event data.</param>
		  private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
		  {
				SetStatus("Fetching Metadata...");
				GetMetaData();
		  }

		  /// <summary>
		  /// Handles the ProgressChanged event of the backgroundWorker1 control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="ProgressChangedEventArgs" /> instance containing the event data.</param>
		  private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
		  {
				var objectTypes = (ObjectTypes)e.UserState;
				switch (objectTypes)
				{
					 case ObjectTypes.Columns:
						  SetStatus("Columns Fetched...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.DataSourceInformation:
						  SetStatus("DataSourceInformation Fetched...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.DataTypes:
						  SetStatus("DataTypes Fetched...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.ForeignKeys:
						  SetStatus("ForeignKeys Fetched...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.IndexColumns:
						  SetStatus("IndexColumns Fetched...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.Indexes:
						  SetStatus("Indexes Fetched...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.InstanceInformation:
						  SetStatus("InstanceInformation Fetched...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.ProcedureParameters:
						  SetStatus("ProcedureParameters Fetched...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.Procedures:
						  SetStatus("Procedures Fetched...", e.ProgressPercentage);
						  FillProcedures();
						  FillFunction();
						  break;

					 case ObjectTypes.ReservedWords:
						  SetStatus("ReservedWords Fetched...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.Restrictions:
						  SetStatus("Restrictions Fetched...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.Tables:
						  SetStatus("Tables Fetched...", e.ProgressPercentage);
						  FillTables();
						  break;

					 case ObjectTypes.Triggers:
						  SetStatus("Triggers Fetched...", e.ProgressPercentage);
						  FillTriggers();
						  break;

					 case ObjectTypes.UserDefinedDataTypes:
						  SetStatus("UserDefinedDataTypes Fetched...", e.ProgressPercentage);
						  FillUDDTs();
						  break;

					 case ObjectTypes.Users:
						  SetStatus("Users Fetched...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.ViewColumns:
						  SetStatus("ViewColumns Fetched...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.Views:
						  FillViews();
						  break;
				}
		  }

		  /// <summary>
		  /// Handles the RunWorkerCompleted event of the backgroundWorker1 control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="RunWorkerCompletedEventArgs" /> instance containing the event data.</param>
		  private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
		  {
				SetStatus("Idle...", 100);
				EnableExportButtonUI();
				GenerateData();
		  }

		  /// <summary>
		  /// Handles the DoWork event of the backgroundWorker3 control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="DoWorkEventArgs" /> instance containing the event data.</param>
		  private void backgroundWorker3_DoWork(object sender, DoWorkEventArgs e)
		  {
				SetStatus("Generating PDF...");
				GeneratePdf();
		  }

		  /// <summary>
		  /// Handles the ProgressChanged event of the backgroundWorker3 control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="ProgressChangedEventArgs" /> instance containing the event data.</param>
		  private void backgroundWorker3_ProgressChanged(object sender, ProgressChangedEventArgs e)
		  {
				var objectTypes = (ObjectTypes)e.UserState;
				switch (objectTypes)
				{
					 case ObjectTypes.Columns:
						  SetStatus("Columns Fetched...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.DataSourceInformation:
						  SetStatus("DataSourceInformation Fetched...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.DataTypes:
						  SetStatus("DataTypes Fetched...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.ForeignKeys:
						  SetStatus("ForeignKeys Fetched...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.IndexColumns:
						  SetStatus("IndexColumns Fetched...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.Indexes:
						  SetStatus("Indexes Fetched...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.InstanceInformation:
						  SetStatus("InstanceInformation Fetched...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.ProcedureParameters:
						  SetStatus("ProcedureParameters Fetched...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.Procedures:
						  SetStatus("Procedures Fetched...", e.ProgressPercentage);
						  FillProcedures();
						  FillFunction();
						  break;

					 case ObjectTypes.ReservedWords:
						  SetStatus("ReservedWords Fetched...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.Restrictions:
						  SetStatus("Restrictions Fetched...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.Tables:
						  SetStatus("Tables Fetched...", e.ProgressPercentage);
						  FillTables();
						  break;

					 case ObjectTypes.Triggers:
						  SetStatus("Triggers Fetched...", e.ProgressPercentage);
						  FillTriggers();
						  break;

					 case ObjectTypes.UserDefinedDataTypes:
						  SetStatus("UserDefinedDataTypes Fetched...", e.ProgressPercentage);
						  FillUDDTs();
						  break;

					 case ObjectTypes.Users:
						  SetStatus("Users Fetched...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.ViewColumns:
						  SetStatus("ViewColumns Fetched...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.Views:
						  FillViews();
						  break;

					 case ObjectTypes.None:
						  SetStatus("Processing...", e.ProgressPercentage);
						  break;
				}
		  }

		  /// <summary>
		  /// Handles the RunWorkerCompleted event of the backgroundWorker3 control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="RunWorkerCompletedEventArgs" /> instance containing the event data.</param>
		  private void backgroundWorker3_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
		  {
				SetStatus("Idle...", 100);
		  }

		  /// <summary>
		  /// Handles the Click event of the btnFetch control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void btnFetch_Click(object sender, EventArgs e)
		  {
				Fetch();
		  }

		  /// <summary>
		  /// Fetches this instance.
		  /// </summary>
		  private void Fetch()
		  {
				OpenConnection(txtSQLServer.Text, chkIntegratedSecurity.Checked, txtUserName.Text, txtUserPassword.Text,
								ddlDatabase.Text);
				Utility.DBConnection = DBConnection;
				Utility.DatabaseServer = txtSQLServer.Text;
				Utility.DatabaseName = ddlDatabase.Text;

				backgroundWorker1.RunWorkerAsync();
		  }

		  /// <summary>
		  /// Generates the PDF.
		  /// </summary>
		  private void GeneratePdf()
		  {
				MergeMultiplePDFReportsIntoSinglePDFHierarchicalView(saveFileDialogPDF.FileName);
		  }

		  /// <summary>
		  /// Gets the meta data.
		  /// </summary>
		  private void GetMetaData()
		  {
				SetStatus("Fetching Columns...");
				ColumnsHelper.GetColumns();
				backgroundWorker1.ReportProgress(5, ObjectTypes.Columns);

				SetStatus("Fetching ForeignKeys...");
				ForeignKeysHelper.GetForeignKeys();
				backgroundWorker1.ReportProgress(10, ObjectTypes.ForeignKeys);

				SetStatus("Fetching IndexColumns...");
				IndexColumnsHelper.GetIndexColumns();
				backgroundWorker1.ReportProgress(15, ObjectTypes.IndexColumns);

				SetStatus("Fetching Indexes...");
				IndexesHelper.GetIndexes();
				backgroundWorker1.ReportProgress(20, ObjectTypes.Indexes);

				SetStatus("Fetching Tables...");
				TablesHelper.GetTables();
				backgroundWorker1.ReportProgress(25, ObjectTypes.Tables);

				SetStatus("Fetching ViewColumns...");
				ViewColumnsHelper.GetViewColumns();
				backgroundWorker1.ReportProgress(30, ObjectTypes.ViewColumns);

				SetStatus("Fetching Views...");
				ViewsHelper.GetViews();
				backgroundWorker1.ReportProgress(35, ObjectTypes.Views);

				SetStatus("Fetching ProcedureParameters...");
				ProcedureParametersHelper.GetProcedureParameters();
				backgroundWorker1.ReportProgress(40, ObjectTypes.ProcedureParameters);

				SetStatus("Fetching Procedures...");
				ProceduresHelper.GetProcedures();
				backgroundWorker1.ReportProgress(45, ObjectTypes.Procedures);

				SetStatus("Fetching Triggers...");
				SMOHelper.TriggersHelper.GetTriggers(Utility.DatabaseName);
				backgroundWorker1.ReportProgress(50, ObjectTypes.Triggers);

				SetStatus("Fetching UserDefinedDataTypes...");
				SMOHelper.UserDefinedDataTypesHelper.GetUserDefinedDataTypes(Utility.DatabaseName);
				backgroundWorker1.ReportProgress(55, ObjectTypes.UserDefinedDataTypes);

				SetStatus("Fetching InstanceInformation...");
				InstanceInformationHelper.GetInstanceInformation();
				backgroundWorker1.ReportProgress(60, ObjectTypes.InstanceInformation);

				SetStatus("Fetching DataSourceInformation...");
				DataSourceInformationHelper.GetDataSourceInformation();
				backgroundWorker1.ReportProgress(65, ObjectTypes.DataSourceInformation);

				SetStatus("Fetching DataTypes...");
				DataTypesHelper.GetDataTypes();
				backgroundWorker1.ReportProgress(70, ObjectTypes.DataTypes);

				SetStatus("Fetching Restrictions...");
				RestrictionsHelper.GetRestrictions();
				backgroundWorker1.ReportProgress(75, ObjectTypes.Restrictions);

				SetStatus("Fetching ReservedWords...");
				ReservedWordsHelper.GetReservedWords();
				backgroundWorker1.ReportProgress(80, ObjectTypes.ReservedWords);

				SetStatus("Fetching Users...");
				UsersHelper.GetUsers();
				backgroundWorker1.ReportProgress(85, ObjectTypes.Users);
		  }

		  #endregion "Fetch Button Click Handling"

		  #region "GenerateData handling"

		  /// <summary>
		  /// Handles the DoWork event of the backgroundWorker2 control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="DoWorkEventArgs" /> instance containing the event data.</param>
		  private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
		  {
				SetStatus("Writing Metadata...");
				WriteMetaDataInXML();
		  }

		  /// <summary>
		  /// Handles the ProgressChanged event of the backgroundWorker2 control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="ProgressChangedEventArgs" /> instance containing the event data.</param>
		  private void backgroundWorker2_ProgressChanged(object sender, ProgressChangedEventArgs e)
		  {
				var objectTypes = (ObjectTypes)e.UserState;
				switch (objectTypes)
				{
					 case ObjectTypes.Columns:
						  SetStatus("Columns Written...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.DataSourceInformation:
						  SetStatus("DataSourceInformation Written...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.DataTypes:
						  SetStatus("DataTypes Written...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.ForeignKeys:
						  SetStatus("ForeignKeys Written...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.IndexColumns:
						  SetStatus("IndexColumns Written...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.Indexes:
						  SetStatus("Indexes Written...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.InstanceInformation:
						  SetStatus("InstanceInformation Written...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.ProcedureParameters:
						  SetStatus("ProcedureParameters Written...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.Procedures:
						  SetStatus("Procedures Written...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.ReservedWords:
						  SetStatus("ReservedWords Written...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.Restrictions:
						  SetStatus("Restrictions Written...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.Tables:
						  SetStatus("Tables Written...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.Triggers:
						  SetStatus("Triggers Written...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.UserDefinedDataTypes:
						  SetStatus("UserDefinedDataTypes Written...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.Users:
						  SetStatus("Users Written...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.ViewColumns:
						  SetStatus("ViewColumns Written...", e.ProgressPercentage);
						  break;

					 case ObjectTypes.Views:
						  break;
				}
		  }

		  /// <summary>
		  /// Handles the RunWorkerCompleted event of the backgroundWorker2 control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="RunWorkerCompletedEventArgs" /> instance containing the event data.</param>
		  private void backgroundWorker2_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
		  {
				SetStatus("Idle...", 100);

				FillAllReportTabPages();
				lblMessage.Text = "Documentation is generated, please refer to individual tabs for details.";
				SetStatus("Idle...", 0);
		  }

		  /// <summary>
		  /// Enables the export button UI.
		  /// </summary>
		  private void EnableExportButtonUI()
		  {
				btnExporttoExcel.Enabled = true;
				btnExporttoPDF.Enabled = true;
				btnExporttoXML.Enabled = true;
		  }

		  /// <summary>
		  /// Generates the data.
		  /// </summary>
		  private void GenerateData()
		  {
				SetStatus("Idle...", 0);
				backgroundWorker2.RunWorkerAsync();
		  }

		  /// <summary>
		  /// Writes the meta data in XML.
		  /// </summary>
		  private void WriteMetaDataInXML()
		  {
				try
				{
					 SetStatus("Writing Columns...");
					 ColumnsHelper.WriteColumns();
					 backgroundWorker2.ReportProgress(5, ObjectTypes.Columns);

					 SetStatus("Writing ForeignKeys...");
					 ForeignKeysHelper.WriteForeignKeys();
					 backgroundWorker2.ReportProgress(10, ObjectTypes.ForeignKeys);

					 SetStatus("Writing IndexColumns...");
					 IndexColumnsHelper.WriteIndexColumns();
					 backgroundWorker2.ReportProgress(15, ObjectTypes.IndexColumns);

					 SetStatus("Writing Indexes...");
					 IndexesHelper.WriteIndexes();
					 backgroundWorker2.ReportProgress(20, ObjectTypes.Indexes);

					 SetStatus("Writing Tables...");
					 TablesHelper.WriteTables();
					 backgroundWorker2.ReportProgress(25, ObjectTypes.Tables);

					 SetStatus("Writing ViewColumns...");
					 ViewColumnsHelper.WriteViewColumns();
					 backgroundWorker2.ReportProgress(30, ObjectTypes.ViewColumns);

					 SetStatus("Writing Views...");
					 ViewsHelper.WriteViews();
					 backgroundWorker2.ReportProgress(35, ObjectTypes.Views);

					 SetStatus("Writing ProcedureParameters...");
					 ProcedureParametersHelper.WriteProcedureParameters();
					 backgroundWorker2.ReportProgress(40, ObjectTypes.ProcedureParameters);

					 SetStatus("Writing Procedures...");
					 ProceduresHelper.WriteProcedures();
					 backgroundWorker2.ReportProgress(45, ObjectTypes.Procedures);

					 SetStatus("Writing Triggers...");
					 SMOHelper.TriggersHelper.WriteTriggers();
					 backgroundWorker2.ReportProgress(50, ObjectTypes.Triggers);

					 SetStatus("Writing UserDefinedDataTypes...");
					 SMOHelper.UserDefinedDataTypesHelper.WriteUserDefinedDataTypes();
					 backgroundWorker2.ReportProgress(55, ObjectTypes.UserDefinedDataTypes);

					 SetStatus("Writing InstanceInformation...");
					 InstanceInformationHelper.WriteInstanceInformation();
					 backgroundWorker2.ReportProgress(60, ObjectTypes.InstanceInformation);

					 SetStatus("Writing DataSourceInformation...");
					 DataSourceInformationHelper.WriteDataSourceInformation();
					 backgroundWorker2.ReportProgress(65, ObjectTypes.DataSourceInformation);

					 SetStatus("Writing DataTypes...");
					 DataTypesHelper.WriteDataTypes();
					 backgroundWorker2.ReportProgress(70, ObjectTypes.DataTypes);

					 SetStatus("Writing Restrictions...");
					 RestrictionsHelper.WriteRestrictions();
					 backgroundWorker2.ReportProgress(75, ObjectTypes.Restrictions);

					 SetStatus("Writing ReservedWords...");
					 ReservedWordsHelper.WriteReservedWords();
					 backgroundWorker2.ReportProgress(80, ObjectTypes.ReservedWords);

					 SetStatus("Writing Users...");
					 UsersHelper.WriteUsers();
					 backgroundWorker2.ReportProgress(85, ObjectTypes.Users);
				}
				catch (Exception ex)
				{
					 MessageBox.Show(ex.Message + Environment.NewLine + ex.StackTrace);
				}
		  }

		  #endregion "GenerateData handling"

		  #region "Set Status delegate Handling"

		  /// <summary>
		  ///
		  /// </summary>
		  /// <param name="t">The t.</param>
		  private delegate void aDelegate(string t);

		  /// <summary>
		  /// Sets the status.
		  /// </summary>
		  /// <param name="message">The message.</param>
		  private void SetStatus(string message)
		  {
				Invoke(new aDelegate(SetToolStripText), message);
		  }

		  /// <summary>
		  /// Sets the status.
		  /// </summary>
		  /// <param name="message">The message.</param>
		  /// <param name="percentage">The percentage.</param>
		  private void SetStatus(string message, int percentage)
		  {
				Invoke(new aDelegate(SetToolStripText), message);
				pbCopy.Value = percentage;
		  }

		  /// <summary>
		  /// Sets the tool strip text.
		  /// </summary>
		  /// <param name="text">The text.</param>
		  private void SetToolStripText(string text)
		  {
				tsStatus.Text = text;
		  }

		  #endregion "Set Status delegate Handling"

		  #region Radio button handling for Check/Uncheck/Toggle

		  /// <summary>
		  /// Adjusts the list view checkboxes.
		  /// </summary>
		  /// <param name="lv">The lv.</param>
		  /// <param name="state">if set to <c>true</c> [state].</param>
		  /// <param name="toggle">if set to <c>true</c> [toggle].</param>
		  private void AdjustListViewCheckboxes(ListView lv, bool state, bool toggle)
		  {
				foreach (ListViewItem item in lv.Items)
				{
					 if (!toggle)
						  item.Checked = state;
					 else
						  item.Checked = !item.Checked;
				}
		  }

		  /// <summary>
		  /// Handles the CheckedChanged event of the radCheckFunctions control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radCheckFunctions_CheckedChanged(object sender, EventArgs e)
		  {
				if (((RadioButton)(sender)).Checked)
					 AdjustListViewCheckboxes(listViewFunctions, radCheckFunctions.Checked, false);
		  }

		  /// <summary>
		  /// Handles the CheckedChanged event of the radCheckProcedured control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radCheckProcedured_CheckedChanged(object sender, EventArgs e)
		  {
				if (((RadioButton)(sender)).Checked)
					 AdjustListViewCheckboxes(listViewProcedures, radCheckProcedured.Checked, false);
		  }

		  /// <summary>
		  /// Handles the CheckedChanged event of the radCheckTables control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radCheckTables_CheckedChanged(object sender, EventArgs e)
		  {
				if (((RadioButton)(sender)).Checked)
					 AdjustListViewCheckboxes(listViewTables, radCheckTables.Checked, false);
		  }

		  /// <summary>
		  /// Handles the CheckedChanged event of the radCheckTriggers control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radCheckTriggers_CheckedChanged(object sender, EventArgs e)
		  {
				if (((RadioButton)(sender)).Checked)
					 AdjustListViewCheckboxes(listViewTriggers, radCheckTriggers.Checked, false);
		  }

		  /// <summary>
		  /// Handles the CheckedChanged event of the radCheckUDDTs control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radCheckUDDTs_CheckedChanged(object sender, EventArgs e)
		  {
				if (((RadioButton)(sender)).Checked)
					 AdjustListViewCheckboxes(listviewUDDT, radCheckUDDTs.Checked, false);
		  }

		  /// <summary>
		  /// Handles the CheckedChanged event of the radCheckViews control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radCheckViews_CheckedChanged(object sender, EventArgs e)
		  {
				if (((RadioButton)(sender)).Checked)
					 AdjustListViewCheckboxes(listViewViews, radCheckViews.Checked, false);
		  }

		  /// <summary>
		  /// Handles the CheckedChanged event of the radToggleFunctions control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radToggleFunctions_CheckedChanged(object sender, EventArgs e)
		  {
				if (((RadioButton)(sender)).Checked)
					 AdjustListViewCheckboxes(listViewFunctions, radToggleFunctions.Checked, true);
		  }

		  /// <summary>
		  /// Handles the CheckedChanged event of the radToggleProcedures control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radToggleProcedures_CheckedChanged(object sender, EventArgs e)
		  {
				if (((RadioButton)(sender)).Checked)
					 AdjustListViewCheckboxes(listViewProcedures, radToggleProcedures.Checked, true);
		  }

		  /// <summary>
		  /// Handles the CheckedChanged event of the radToggleTables control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radToggleTables_CheckedChanged(object sender, EventArgs e)
		  {
				if (((RadioButton)(sender)).Checked)
					 AdjustListViewCheckboxes(listViewTables, radToggleTables.Checked, true);
		  }

		  /// <summary>
		  /// Handles the CheckedChanged event of the radToggleTriggers control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radToggleTriggers_CheckedChanged(object sender, EventArgs e)
		  {
				if (((RadioButton)(sender)).Checked)
					 AdjustListViewCheckboxes(listViewTriggers, radToggleTriggers.Checked, true);
		  }

		  /// <summary>
		  /// Handles the CheckedChanged event of the radToggleUDDTs control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radToggleUDDTs_CheckedChanged(object sender, EventArgs e)
		  {
				if (((RadioButton)(sender)).Checked)
					 AdjustListViewCheckboxes(listviewUDDT, radToggleUDDTs.Checked, true);
		  }

		  /// <summary>
		  /// Handles the CheckedChanged event of the radToggleViews control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radToggleViews_CheckedChanged(object sender, EventArgs e)
		  {
				if (((RadioButton)(sender)).Checked)
					 AdjustListViewCheckboxes(listViewViews, radToggleViews.Checked, true);
		  }

		  /// <summary>
		  /// Handles the CheckedChanged event of the radUncheckFunctions control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radUncheckFunctions_CheckedChanged(object sender, EventArgs e)
		  {
				if (((RadioButton)(sender)).Checked)
					 AdjustListViewCheckboxes(listViewFunctions, !radUncheckFunctions.Checked, false);
		  }

		  /// <summary>
		  /// Handles the CheckedChanged event of the radUncheckProcedures control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radUncheckProcedures_CheckedChanged(object sender, EventArgs e)
		  {
				if (((RadioButton)(sender)).Checked)
					 AdjustListViewCheckboxes(listViewProcedures, !radUncheckProcedures.Checked, false);
		  }

		  /// <summary>
		  /// Handles the CheckedChanged event of the radUncheckTables control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radUncheckTables_CheckedChanged(object sender, EventArgs e)
		  {
				if (((RadioButton)(sender)).Checked)
					 AdjustListViewCheckboxes(listViewTables, !radUncheckTables.Checked, false);
		  }

		  /// <summary>
		  /// Handles the CheckedChanged event of the radUncheckTriggers control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radUncheckTriggers_CheckedChanged(object sender, EventArgs e)
		  {
				if (((RadioButton)(sender)).Checked)
					 AdjustListViewCheckboxes(listViewTriggers, !radUncheckTriggers.Checked, false);
		  }

		  /// <summary>
		  /// Handles the CheckedChanged event of the radUncheckUDDTs control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radUncheckUDDTs_CheckedChanged(object sender, EventArgs e)
		  {
				if (((RadioButton)(sender)).Checked)
					 AdjustListViewCheckboxes(listviewUDDT, !radUncheckUDDTs.Checked, false);
		  }

		  /// <summary>
		  /// Handles the CheckedChanged event of the radUncheckViews control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radUncheckViews_CheckedChanged(object sender, EventArgs e)
		  {
				if (((RadioButton)(sender)).Checked)
					 AdjustListViewCheckboxes(listViewViews, !radUncheckViews.Checked, false);
		  }

		  #endregion Radio button handling for Check/Uncheck/Toggle

		  #region "Report Master Detail Handling (Drillthrough)"

		  /// <summary>
		  /// Fills the function details.
		  /// </summary>
		  /// <param name="functionName">Name of the function.</param>
		  /// <param name="lr">The lr.</param>
		  /// <param name="e">The <see cref="SubreportProcessingEventArgs" /> instance containing the event data.</param>
		  private void FillFunctionDetails(string functionName, LocalReport lr, SubreportProcessingEventArgs e)
		  {
				var dataSet = new DataSet();
				dataSet.ReadXml(appLocation + "\\xml\\" + functionName + ".xml");

				var functionProperties = new DataTable("FunctionProperties");
				var functionINParameters = new DataTable("FunctionINParameters");
				var functionOUTParameters = new DataTable("FunctionOUTParameters");
				var sql = new DataTable("SQL");

				if (dataSet.Tables["FunctionProperties"] != null)
					 functionProperties = dataSet.Tables["FunctionProperties"];
				if (dataSet.Tables["FunctionINParameters"] != null)
					 functionINParameters = dataSet.Tables["FunctionINParameters"];
				if (dataSet.Tables["FunctionOUTParameters"] != null)
					 functionOUTParameters = dataSet.Tables["FunctionOUTParameters"];
				if (dataSet.Tables["SQL"] != null)
					 sql = dataSet.Tables["SQL"];

				if (e == null)
				{
					 lr.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_FunctionProperties", functionProperties));
					 lr.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_FunctionINParameters", functionINParameters));
					 lr.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_FunctionOUTParameters", functionOUTParameters));
					 lr.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_SQL", sql));
					 lr.Refresh();
				}
				else
				{
					 e.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_FunctionProperties", functionProperties));
					 e.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_FunctionINParameters", functionINParameters));
					 e.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_FunctionOUTParameters", functionOUTParameters));
					 e.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_SQL", sql));
				}
		  }

		  /// <summary>
		  /// Fills the procedure details.
		  /// </summary>
		  /// <param name="procedureName">Name of the procedure.</param>
		  /// <param name="lr">The lr.</param>
		  /// <param name="e">The <see cref="SubreportProcessingEventArgs" /> instance containing the event data.</param>
		  private void FillProcedureDetails(string procedureName, LocalReport lr, SubreportProcessingEventArgs e)
		  {
				var dataSet = new DataSet();
				dataSet.ReadXml(appLocation + "\\xml\\" + procedureName + ".xml");

				var procedureProperties = new DataTable("ProcedureProperties");
				var procedureINParameters = new DataTable("ProcedureINParameters");
				var procedureOUTParameters = new DataTable("ProcedureOUTParameters");
				var sql = new DataTable("SQL");

				if (dataSet.Tables["ProcedureProperties"] != null)
					 procedureProperties = dataSet.Tables["ProcedureProperties"];
				if (dataSet.Tables["ProcedureINParameters"] != null)
					 procedureINParameters = dataSet.Tables["ProcedureINParameters"];
				if (dataSet.Tables["ProcedureOUTParameters"] != null)
					 procedureINParameters = dataSet.Tables["ProcedureOUTParameters"];
				if (dataSet.Tables["SQL"] != null)
					 sql = dataSet.Tables["SQL"];

				if (e == null)
				{
					 lr.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_ProcedureProperties", procedureProperties));
					 lr.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_ProcedureINParameters", procedureINParameters));
					 lr.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_ProcedureOUTParameters", procedureOUTParameters));
					 lr.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_SQL", sql));
					 lr.Refresh();
				}
				else
				{
					 e.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_ProcedureProperties", procedureProperties));
					 e.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_ProcedureINParameters", procedureINParameters));
					 e.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_ProcedureOUTParameters", procedureOUTParameters));
					 e.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_SQL", sql));
				}
		  }

		  /// <summary>
		  /// Fills the table details.
		  /// </summary>
		  /// <param name="tableName">Name of the table.</param>
		  /// <param name="lr">The lr.</param>
		  /// <param name="e">The <see cref="SubreportProcessingEventArgs" /> instance containing the event data.</param>
		  private void FillTableDetails(string tableName, LocalReport lr, SubreportProcessingEventArgs e)
		  {
				var dataSet = new DataSet();
				dataSet.ReadXml(appLocation + "\\xml\\" + tableName + ".xml");

				var tableProperties = new DataTable("TableProperties");
				var columns = new DataTable("Columns");
				var indexes = new DataTable("Indexes");
				var foreignKeys = new DataTable("ForeignKeys");
				var sql = new DataTable("SQL");

				if (dataSet.Tables["TableProperties"] != null)
					 tableProperties = dataSet.Tables["TableProperties"];
				if (dataSet.Tables["Columns"] != null)
					 columns = dataSet.Tables["Columns"];
				if (dataSet.Tables["Indexes"] != null)
					 indexes = dataSet.Tables["Indexes"];
				if (dataSet.Tables["ForeignKeys"] != null)
					 foreignKeys = dataSet.Tables["ForeignKeys"];
				if (dataSet.Tables["SQL"] != null)
					 sql = dataSet.Tables["SQL"];

				if (e == null)
				{
					 lr.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_TableProperties", tableProperties));
					 lr.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_Columns", columns));
					 lr.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_Indexes", indexes));
					 lr.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_ForeignKeys", foreignKeys));
					 lr.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_SQL", sql));
					 lr.Refresh();
				}
				else
				{
					 e.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_TableProperties", tableProperties));
					 e.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_Columns", columns));
					 e.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_Indexes", indexes));
					 e.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_ForeignKeys", foreignKeys));
					 e.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_SQL", sql));
				}
		  }

		  /// <summary>
		  /// Fills the trigger details.
		  /// </summary>
		  /// <param name="triggerName">Name of the trigger.</param>
		  /// <param name="lr">The lr.</param>
		  /// <param name="e">The <see cref="SubreportProcessingEventArgs" /> instance containing the event data.</param>
		  private void FillTriggerDetails(string triggerName, LocalReport lr, SubreportProcessingEventArgs e)
		  {
				var dataSet = new DataSet();
				dataSet.ReadXml(appLocation + "\\xml\\" + triggerName + ".xml");

				var tableProperties = new DataTable("TableProperties");
				var tableType = new DataTable("TableType");
				var sql = new DataTable("SQL");

				if (dataSet.Tables["TableProperties"] != null)
					 tableProperties = dataSet.Tables["TableProperties"];
				if (dataSet.Tables["TableType"] != null)
					 tableType = dataSet.Tables["TableType"];
				if (dataSet.Tables["SQL"] != null)
					 sql = dataSet.Tables["SQL"];

				if (e == null)
				{
					 lr.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_TableProperties", tableProperties));
					 lr.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_TableType", tableType));
					 lr.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_SQL", sql));
					 lr.Refresh();
				}
				else
				{
					 e.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_TableProperties", tableProperties));
					 e.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_TableType", tableType));
					 e.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_SQL", sql));
				}
		  }

		  /// <summary>
		  /// Fills the user defined data type details.
		  /// </summary>
		  /// <param name="uddtName">Name of the uddt.</param>
		  /// <param name="lr">The lr.</param>
		  /// <param name="e">The <see cref="SubreportProcessingEventArgs" /> instance containing the event data.</param>
		  private void FillUserDefinedDataTypeDetails(string uddtName, LocalReport lr, SubreportProcessingEventArgs e)
		  {
				var dataSet = new DataSet();
				dataSet.ReadXml(appLocation + "\\xml\\" + uddtName + ".xml");

				var tableProperties = new DataTable("TableProperties");
				var columnsDefinedOn = new DataTable("ColumnsDefinedOn");
				var sql = new DataTable("SQL");

				if (dataSet.Tables["TableProperties"] != null)
					 tableProperties = dataSet.Tables["TableProperties"];
				if (dataSet.Tables["ColumnsDefinedOn"] != null)
					 columnsDefinedOn = dataSet.Tables["ColumnsDefinedOn"];
				if (dataSet.Tables["SQL"] != null)
					 sql = dataSet.Tables["SQL"];

				if (e == null)
				{
					 lr.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_TableProperties", tableProperties));
					 lr.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_ColumnsDefinedOn", columnsDefinedOn));
					 lr.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_SQL", sql));
					 lr.Refresh();
				}
				else
				{
					 e.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_TableProperties", tableProperties));
					 e.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_ColumnsDefinedOn", columnsDefinedOn));
					 e.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_SQL", sql));
				}
		  }

		  /// <summary>
		  /// Fills the view details.
		  /// </summary>
		  /// <param name="viewName">Name of the view.</param>
		  /// <param name="lr">The lr.</param>
		  /// <param name="e">The <see cref="SubreportProcessingEventArgs" /> instance containing the event data.</param>
		  private void FillViewDetails(string viewName, LocalReport lr, SubreportProcessingEventArgs e)
		  {
				var dataSet = new DataSet();
				dataSet.ReadXml(appLocation + "\\xml\\" + viewName + ".xml");

				var tableProperties = new DataTable("TableProperties");
				var columns = new DataTable("Columns");
				var sql = new DataTable("SQL");

				if (dataSet.Tables["TableProperties"] != null)
					 tableProperties = dataSet.Tables["TableProperties"];
				if (dataSet.Tables["Columns"] != null)
					 columns = dataSet.Tables["Columns"];
				if (dataSet.Tables["SQL"] != null)
					 sql = dataSet.Tables["SQL"];

				if (e == null)
				{
					 lr.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_TableProperties", tableProperties));
					 lr.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_Columns", columns));
					 lr.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_SQL", sql));
					 lr.Refresh();
				}
				else
				{
					 e.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_TableProperties", tableProperties));
					 e.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_Columns", columns));
					 e.DataSources.Add(new ReportDataSource("SQLDocEngine_Entities_SQL", sql));
				}
		  }

		  /// <summary>
		  /// This event is fired, when in master-detail view the sub report hyperlink is clicked.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="DrillthroughEventArgs" /> instance containing the event data.</param>
		  private void reportViewer_Drillthrough(object sender, DrillthroughEventArgs e)
		  {
				ReportParameterInfoCollection rpic = e.Report.GetParameters();
				string objectName = rpic["ObjectName"].Values[0];
				var lr = (LocalReport)e.Report;

				string report = ((ReportViewer)(sender)).LocalReport.DisplayName;

				switch (report)
				{
					 case "TableList":
						  FillTableDetails(objectName, lr, null);
						  break;

					 case "ViewList":
						  FillViewDetails(objectName, lr, null);
						  break;

					 case "ProcedureList":
						  FillProcedureDetails(objectName, lr, null);
						  break;

					 case "FunctionList":
						  FillFunctionDetails(objectName, lr, null);
						  break;

					 case "TriggerList":
						  FillTriggerDetails(objectName, lr, null);
						  break;

					 case "UserDefinedDataTypeList":
						  FillUserDefinedDataTypeDetails(objectName, lr, null);
						  break;
				}
		  }

		  /// <summary>
		  /// This event is fired, when in hierarchical view the sub report is selected.
		  /// </summary>
		  /// <param name="sender">The sender.</param>
		  /// <param name="e">The <see cref="SubreportProcessingEventArgs" /> instance containing the event data.</param>
		  private void SubreportProcessingEventHandler(object sender, SubreportProcessingEventArgs e)
		  {
				ReportParameterInfoCollection rpic = e.Parameters;
				string objectName = rpic["ObjectName"].Values[0];
				var lr = (LocalReport)sender;

				string report = lr.DisplayName;

				switch (report)
				{
					 case "TableList":
						  FillTableDetails(objectName, lr, null);
						  break;

					 case "TableMap":
						  FillTableDetails(objectName, lr, e);
						  break;

					 case "ViewList":
						  FillViewDetails(objectName, lr, null);
						  break;

					 case "ViewMap":
						  FillViewDetails(objectName, lr, e);
						  break;

					 case "ProcedureList":
						  FillProcedureDetails(objectName, lr, null);
						  break;

					 case "ProcedureMap":
						  FillProcedureDetails(objectName, lr, e);
						  break;

					 case "FunctionList":
						  FillFunctionDetails(objectName, lr, null);
						  break;

					 case "FunctionMap":
						  FillFunctionDetails(objectName, lr, e);
						  break;

					 case "TriggerList":
						  FillTriggerDetails(objectName, lr, null);
						  break;

					 case "TriggerMap":
						  FillTriggerDetails(objectName, lr, e);
						  break;

					 case "UserDefinedDataTypeList":
						  FillUserDefinedDataTypeDetails(objectName, lr, null);
						  break;

					 case "UserDefinedDataTypeMap":
						  FillUserDefinedDataTypeDetails(objectName, lr, e);
						  break;
				}
		  }

		  #region "Helpers"

		  /// <summary>
		  /// Builds the connection string.
		  /// </summary>
		  /// <param name="serverName">Name of the server.</param>
		  /// <param name="isIntegratedSecurity">if set to <c>true</c> [is integrated security].</param>
		  /// <param name="userName">Name of the user.</param>
		  /// <param name="password">The password.</param>
		  /// <param name="databaseName">Name of the database.</param>
		  /// <returns></returns>
		  private string BuildConnectionString(string serverName, bool isIntegratedSecurity, string userName, string password,
											  string databaseName)
		  {
				string conString;

				conString = "Data Source=";
				conString += serverName + ";";
				conString += "Initial Catalog=";
				conString += databaseName + ";";

				if (!isIntegratedSecurity)
					 conString += "User Id=" + userName + ";Password=" + password + ";";
				else
					 conString += "Trusted_Connection=True;";

				return conString;
		  }

		  /// <summary>
		  /// Closes the connection.
		  /// </summary>
		  private void CloseConnection()
		  {
				if (dbConnection != null && dbConnection.State == ConnectionState.Open)
					 dbConnection.Close();
		  }

		  /// <summary>
		  /// Opens the connection.
		  /// </summary>
		  /// <param name="serverName">Name of the server.</param>
		  /// <param name="isIntegratedSecurity">if set to <c>true</c> [is integrated security].</param>
		  /// <param name="userName">Name of the user.</param>
		  /// <param name="password">The password.</param>
		  /// <param name="databaseName">Name of the database.</param>
		  /// <returns></returns>
		  private bool OpenConnection(string serverName, bool isIntegratedSecurity, string userName, string password,
									  string databaseName)
		  {
				try
				{
					 dbConnection = new SqlConnection();
					 dbConnection.ConnectionString = BuildConnectionString(serverName, isIntegratedSecurity, userName, password,
																		 databaseName);
					 dbConnection.Open();
					 return true;
				}
				catch
				{
					 return false;
				}
		  }

		  #endregion "Helpers"

		  #region "RadioButton handling"

		  #region "Tables"

		  /// <summary>
		  /// Handles the CheckedChanged event of the radHierarchicalViewTables control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radHierarchicalViewTables_CheckedChanged(object sender, EventArgs e)
		  {
				if (radHierarchicalViewTables.Checked)
					 FillReportTablesHierarchicalView();
		  }

		  /// <summary>
		  /// Handles the CheckedChanged event of the radMasterDetailViewTables control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radMasterDetailViewTables_CheckedChanged(object sender, EventArgs e)
		  {
				if (radMasterDetailViewTables.Checked)
					 FillReportTablesMasterDetailView();
		  }

		  #endregion "Tables"

		  #region "Views"

		  /// <summary>
		  /// Handles the CheckedChanged event of the radHierarchicalViewViews control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radHierarchicalViewViews_CheckedChanged(object sender, EventArgs e)
		  {
				if (radHierarchicalViewViews.Checked)
					 FillReportViewsHierarchicalView();
		  }

		  /// <summary>
		  /// Handles the CheckedChanged event of the radMasterDetailViewViews control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radMasterDetailViewViews_CheckedChanged(object sender, EventArgs e)
		  {
				if (radMasterDetailViewViews.Checked)
					 FillReportViewsMasterDetailView();
		  }

		  #endregion "Views"

		  #region "Procedures"

		  /// <summary>
		  /// Handles the CheckedChanged event of the radHierarchicalViewProcedures control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radHierarchicalViewProcedures_CheckedChanged(object sender, EventArgs e)
		  {
				if (radHierarchicalViewProcedures.Checked)
					 FillReportProceduresHierarchicalView();
		  }

		  /// <summary>
		  /// Handles the CheckedChanged event of the radMasterDetailViewProcedures control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radMasterDetailViewProcedures_CheckedChanged(object sender, EventArgs e)
		  {
				if (radMasterDetailViewProcedures.Checked)
					 FillReportProceduresMasterDetailView();
		  }

		  #endregion "Procedures"

		  #region "Functions"

		  /// <summary>
		  /// Handles the CheckedChanged event of the radHierarchicalViewFunctions control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radHierarchicalViewFunctions_CheckedChanged(object sender, EventArgs e)
		  {
				if (radHierarchicalViewFunctions.Checked)
					 FillReportFunctionsHierarchicalView();
		  }

		  /// <summary>
		  /// Handles the CheckedChanged event of the radMasterDetailViewFunctions control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radMasterDetailViewFunctions_CheckedChanged(object sender, EventArgs e)
		  {
				if (radMasterDetailViewFunctions.Checked)
					 FillReportFuntionsMasterDetailView();
		  }

		  #endregion "Functions"

		  #region "Triggers"

		  /// <summary>
		  /// Handles the CheckedChanged event of the radHierarchicalViewTriggers control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radHierarchicalViewTriggers_CheckedChanged(object sender, EventArgs e)
		  {
				if (radHierarchicalViewTriggers.Checked)
					 FillReportTriggersHierarchicalView();
		  }

		  /// <summary>
		  /// Handles the CheckedChanged event of the radMasterDetailViewTriggers control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radMasterDetailViewTriggers_CheckedChanged(object sender, EventArgs e)
		  {
				if (radMasterDetailViewTriggers.Checked)
					 FillReportTriggersMasterDetailView();
		  }

		  #endregion "Triggers"

		  #region "UDDTs"

		  /// <summary>
		  /// Handles the CheckedChanged event of the radHierarchicalViewUDDTs control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radHierarchicalViewUDDTs_CheckedChanged(object sender, EventArgs e)
		  {
				if (radHierarchicalViewUDDTs.Checked)
					 FillReportUDDTsHierarchicalView();
		  }

		  /// <summary>
		  /// Handles the CheckedChanged event of the radMasterDetailViewUDDTs control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void radMasterDetailViewUDDTs_CheckedChanged(object sender, EventArgs e)
		  {
				if (radMasterDetailViewUDDTs.Checked)
					 FillReportUDDTsMasterDetailView();
		  }

		  #endregion "UDDTs"

		  #endregion "RadioButton handling"

		  #endregion "Report Master Detail Handling (Drillthrough)"

		  /// <summary>
		  /// Adds the system DBS.
		  /// </summary>
		  private void AddSystemDBS()
		  {
				FillComboBox(ddlDatabase, DatabasesHelper.Databases, "database_name", "dbid");
		  }

		  /// <summary>
		  /// Handles the Click event of the btnExporttoPDF control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void btnExporttoPDF_Click(object sender, EventArgs e)
		  {
				saveFileDialogPDF.Filter = "pdf files (*.pdf)|*.pdf";

				if (saveFileDialogPDF.ShowDialog() == DialogResult.OK && saveFileDialogPDF.FileName.Length > 0)
				{
					 backgroundWorker3.RunWorkerAsync();
				}
		  }

		  /// <summary>
		  /// Handles the Click event of the btnExporttoXML control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void btnExporttoXML_Click(object sender, EventArgs e)
		  {
				saveFileDialogXML.Filter = "xml files (*.xml)|*.xml";

				if (saveFileDialogXML.ShowDialog() == DialogResult.OK && saveFileDialogXML.FileName.Length > 0)
				{
					 MergeMultipleXMLReportsIntoSingleXML(saveFileDialogXML.FileName);
				}
		  }

		  /// <summary>
		  /// Handles the CheckedChanged event of the chkHideSystemDB control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void chkHideSystemDB_CheckedChanged(object sender, EventArgs e)
		  {
				if (!chkHideSystemDB.Checked)
					 RemoveSystemDBS();
				else
					 AddSystemDBS();
		  }

		  /// <summary>
		  /// Handles the Click event of the Export_ToolStripMenuItem control.
		  /// </summary>
		  /// <param name="sender">The source of the event.</param>
		  /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
		  private void Export_ToolStripMenuItem_Click(object sender, EventArgs e)
		  {
				var menu = (ToolStripMenuItem)sender;
				string menuText = Convert.ToString(menu.Tag);

				switch (menuText)
				{
					 case "XMLTables":

						  //ExportReport(reportViewerTables, "TableList", "XML");
						  break;

					 case "XMLViews":

						  //ExportReport(reportViewerViews, "", "");
						  break;

					 case "XMLProcedures":

						  //ExportReport(reportViewerProcedures, "", "");
						  break;

					 case "XMLFunctions":

						  //ExportReport(reportViewerFunctions, "", "");
						  break;

					 case "XMLTriggers":

						  //ExportReport(reportViewerTriggers, "", "");
						  break;

					 case "XMLUDDTs":

						  //ExportReport(reportViewerUDDTs, "", "");
						  break;

					 case "PDFTables":
						  ExportReport(reportViewerTables, "TableList", "PDF");
						  break;

					 case "PDFViews":
						  ExportReport(reportViewerViews, "ViewList", "PDF");
						  break;

					 case "PDFProcedures":
						  ExportReport(reportViewerProcedures, "ProcedureList", "PDF");
						  break;

					 case "PDFFunctions":
						  ExportReport(reportViewerFunctions, "FunctionList", "PDF");
						  break;

					 case "PDFTriggers":
						  ExportReport(reportViewerTriggers, "TriggerList", "PDF");
						  break;

					 case "PDFUDDTs":
						  ExportReport(reportViewerUDDTs, "UserDefinedDataTypeList", "PDF");
						  break;

					 case "EXCELTables":
						  ExportReport(reportViewerTables, "TableList", "EXCEL");
						  break;

					 case "EXCELViews":
						  ExportReport(reportViewerViews, "ViewList", "EXCEL");
						  break;

					 case "EXCELProcedures":
						  ExportReport(reportViewerProcedures, "Procedure", "EXCEL");
						  break;

					 case "EXCELFunctions":
						  ExportReport(reportViewerFunctions, "Function", "EXCEL");
						  break;

					 case "EXCELTriggers":
						  ExportReport(reportViewerTriggers, "Trigger", "EXCEL");
						  break;

					 case "EXCELUDDTs":
						  ExportReport(reportViewerUDDTs, "UserDefinedDataTypeList", "EXCEL");
						  break;
				}
		  }

		  /// <summary>
		  /// Exports the report.
		  /// </summary>
		  /// <param name="viewer">The viewer.</param>
		  /// <param name="reportName">Name of the report.</param>
		  /// <param name="format">The format.</param>
		  private void ExportReport(ReportViewer viewer, string reportName, string format)
		  {
				Warning[] warnings;
				string[] streamids;
				string mimeType, encoding, fileNameExtention;
				FileStream fs = null;
				try
				{
					 byte[] bytes = viewer.LocalReport.Render(format, null, out mimeType, out encoding, out fileNameExtention,
															 out streamids, out warnings);
					 format = format.Equals("PDF") ? "pdf" : "xls";
					 fs = new FileStream(reportName + "." + format, FileMode.Create);
					 fs.Write(bytes, 0, bytes.Length);

					 MessageBox.Show(reportName + " exported to " + format + " format", "Info");
				}
				catch (Exception ex)
				{
					 MessageBox.Show(ex.Message);
				}
				finally
				{
					 fs.Close();
				}
		  }

		  /// <summary>
		  /// Merges the multiple PDF reports into single PDF hierarchical view.
		  /// </summary>
		  /// <param name="fileName">Name of the file.</param>
		  private void MergeMultiplePDFReportsIntoSinglePDFHierarchicalView(string fileName)
		  {
				SetStatus("Generate Tables Section...");
				ThreadFillReportTablesHierarchicalView();
				backgroundWorker3.ReportProgress(7, ObjectTypes.Tables);
				Thread.Sleep(1 * 1000);
				SetStatus("Generate Views Section...");
				ThreadFillReportViewsHierarchicalView();
				backgroundWorker3.ReportProgress(14, ObjectTypes.Views);
				Thread.Sleep(1 * 1000);
				SetStatus("Generate Procedures Section...");
				ThreadFillReportProceduresHierarchicalView();
				backgroundWorker3.ReportProgress(21, ObjectTypes.Procedures);
				Thread.Sleep(1 * 1000);
				SetStatus("Generate Functions Section...");
				ThreadFillReportFunctionsHierarchicalView();
				backgroundWorker3.ReportProgress(28, ObjectTypes.ProcedureParameters);
				Thread.Sleep(1 * 1000);
				SetStatus("Generate Triggers Section...");
				ThreadFillReportTriggersHierarchicalView();
				backgroundWorker3.ReportProgress(35, ObjectTypes.Triggers);
				Thread.Sleep(1 * 1000);
				SetStatus("Generate UDDT Section...");
				ThreadFillReportUDDTsHierarchicalView();
				backgroundWorker3.ReportProgress(42, ObjectTypes.UserDefinedDataTypes);
				Thread.Sleep(1 * 1000);

				var reps = new List<MemoryStream>();
				Warning[] warnings;
				string[] streamids;
				string mimeType, encoding, fileNameExtention;
				byte[] bytes = null;

				//string path = Path.GetTempPath();
				try
				{
					 SetStatus("Processing Tables Data...");
					 bytes = reportViewerTables.LocalReport.Render("pdf", null, out mimeType, out encoding, out fileNameExtention,
																 out streamids, out warnings);
					 backgroundWorker3.ReportProgress(49, ObjectTypes.Tables);
					 var ms1 = new MemoryStream();
					 ms1.Write(bytes, 0, bytes.Length);
					 ms1.Flush();
					 reps.Add(ms1);

					 SetStatus("Processing Views Data...");
					 bytes = reportViewerViews.LocalReport.Render("pdf", null, out mimeType, out encoding, out fileNameExtention,
																 out streamids, out warnings);
					 backgroundWorker3.ReportProgress(56, ObjectTypes.Views);
					 var ms2 = new MemoryStream();
					 ms2.Write(bytes, 0, bytes.Length);
					 ms2.Flush();
					 reps.Add(ms2);

					 SetStatus("Processing Procedures Data...");
					 bytes = reportViewerProcedures.LocalReport.Render("pdf", null, out mimeType, out encoding, out fileNameExtention,
																	 out streamids, out warnings);
					 backgroundWorker3.ReportProgress(63, ObjectTypes.Procedures);
					 var ms3 = new MemoryStream();
					 ms3.Write(bytes, 0, bytes.Length);
					 ms3.Flush();
					 reps.Add(ms3);

					 SetStatus("Processing Functions Data...");
					 bytes = reportViewerFunctions.LocalReport.Render("pdf", null, out mimeType, out encoding, out fileNameExtention,
																	 out streamids, out warnings);
					 backgroundWorker3.ReportProgress(70, ObjectTypes.ProcedureParameters);
					 var ms4 = new MemoryStream();
					 ms4.Write(bytes, 0, bytes.Length);
					 ms4.Flush();
					 reps.Add(ms4);

					 SetStatus("Processing Triggers Data...");
					 bytes = reportViewerTriggers.LocalReport.Render("pdf", null, out mimeType, out encoding, out fileNameExtention,
																	 out streamids, out warnings);
					 backgroundWorker3.ReportProgress(77, ObjectTypes.Triggers);
					 var ms5 = new MemoryStream();
					 ms5.Write(bytes, 0, bytes.Length);
					 ms5.Flush();
					 reps.Add(ms5);

					 SetStatus("Processing UDDT Data...");
					 bytes = reportViewerUDDTs.LocalReport.Render("pdf", null, out mimeType, out encoding, out fileNameExtention,
																 out streamids, out warnings);
					 backgroundWorker3.ReportProgress(84, ObjectTypes.UserDefinedDataTypes);
					 var ms6 = new MemoryStream();
					 ms6.Write(bytes, 0, bytes.Length);
					 ms6.Flush();
					 reps.Add(ms6);

					 SetStatus("Saving PDF Report...");
					 PdfMerge.MergeStreams(fileName, reps);
					 backgroundWorker3.ReportProgress(90, ObjectTypes.None);

					 SetStatus("Cleaning Up...");
					 ms1.Close();
					 ms2.Close();
					 ms3.Close();
					 ms4.Close();
					 ms5.Close();
					 ms6.Close();

					 backgroundWorker3.ReportProgress(95, ObjectTypes.None);

					 MessageBox.Show("All data exported successfully to " + fileName);
				}
				catch (Exception ex)
				{
					 Console.WriteLine(ex.Message);
				}
		  }

		  /// <summary>
		  /// Merges the multiple PDF reports into single PDF list view.
		  /// </summary>
		  /// <param name="fileName">Name of the file.</param>
		  private void MergeMultiplePDFReportsIntoSinglePDFListView(string fileName)
		  {
				FillReportTablesMasterDetailView();
				Thread.Sleep(1 * 1000);
				FillReportViewsMasterDetailView();
				Thread.Sleep(1 * 1000);
				FillReportProceduresMasterDetailView();
				Thread.Sleep(1 * 1000);
				FillReportFuntionsMasterDetailView();
				Thread.Sleep(1 * 1000);
				FillReportTriggersMasterDetailView();
				Thread.Sleep(1 * 1000);
				FillReportUDDTsMasterDetailView();
				Thread.Sleep(1 * 1000);

				Warning[] warnings;
				string[] streamids;
				string mimeType, encoding, fileNameExtention;
				byte[] bytes = null;

				try
				{
					 bytes = reportViewerTables.LocalReport.Render("pdf", null, out mimeType, out encoding, out fileNameExtention,
																 out streamids, out warnings);
					 var fs1 = new FileStream("L1.pdf", FileMode.Create);
					 fs1.Write(bytes, 0, bytes.Length);
					 fs1.Close();

					 bytes = reportViewerViews.LocalReport.Render("pdf", null, out mimeType, out encoding, out fileNameExtention,
																 out streamids, out warnings);
					 var fs2 = new FileStream("L2.pdf", FileMode.Create);
					 fs2.Write(bytes, 0, bytes.Length);
					 fs2.Close();

					 bytes = reportViewerProcedures.LocalReport.Render("pdf", null, out mimeType, out encoding, out fileNameExtention,
																	 out streamids, out warnings);
					 var fs3 = new FileStream("L3.pdf", FileMode.Create);
					 fs3.Write(bytes, 0, bytes.Length);
					 fs3.Close();

					 bytes = reportViewerFunctions.LocalReport.Render("pdf", null, out mimeType, out encoding, out fileNameExtention,
																	 out streamids, out warnings);
					 var fs4 = new FileStream("L4.pdf", FileMode.Create);
					 fs4.Write(bytes, 0, bytes.Length);
					 fs4.Close();

					 bytes = reportViewerTriggers.LocalReport.Render("pdf", null, out mimeType, out encoding, out fileNameExtention,
																	 out streamids, out warnings);
					 var fs5 = new FileStream("L5.pdf", FileMode.Create);
					 fs5.Write(bytes, 0, bytes.Length);
					 fs5.Close();

					 bytes = reportViewerUDDTs.LocalReport.Render("pdf", null, out mimeType, out encoding, out fileNameExtention,
																 out streamids, out warnings);
					 var fs6 = new FileStream("L6.pdf", FileMode.Create);
					 fs6.Write(bytes, 0, bytes.Length);
					 fs6.Close();

					 PdfMerge.MergeFiles(fileName, new[] { "L1.pdf", "L2.pdf", "L3.pdf", "L4.pdf", "L5.pdf", "L6.pdf" });
					 MessageBox.Show("All data exported successfully to " + fileName);
				}
				catch (Exception ex)
				{
					 Console.WriteLine(ex.Message);
				}
		  }

		  /// <summary>
		  /// Merges the multiple XML reports into single XML.
		  /// </summary>
		  /// <param name="fileName">Name of the file.</param>
		  private void MergeMultipleXMLReportsIntoSingleXML(string fileName)
		  {
				entireDatabase.Tables.Add(InstanceInformationHelper.InstanceInformation.Copy());
				entireDatabase.Tables.Add(DataSourceInformationHelper.DataSourceInformation.Copy());
				entireDatabase.Tables.Add(DataTypesHelper.DataTypes.Copy());
				entireDatabase.Tables.Add(RestrictionsHelper.Restrictions.Copy());
				entireDatabase.Tables.Add(ReservedWordsHelper.ReservedWords.Copy());
				entireDatabase.Tables.Add(UsersHelper.Users.Copy());
				entireDatabase.Tables.Add(DatabasesHelper.Databases.Copy());

				entireDatabase.Tables.Add(TablesHelper.Tables.Copy());
				entireDatabase.Tables.Add(ColumnsHelper.Columns.Copy());
				entireDatabase.Tables.Add(AllColumnsHelper.AllColumns.Copy());
				entireDatabase.Tables.Add(ColumnSetColumnsHelper.ColumnSetColumns.Copy());
				entireDatabase.Tables.Add(StructuredTypeMembersHelper.StructuredTypeMembers.Copy());
				entireDatabase.Tables.Add(ViewsHelper.Views.Copy());
				entireDatabase.Tables.Add(ViewColumnsHelper.ViewColumns.Copy());
				entireDatabase.Tables.Add(ProcedureParametersHelper.ProcedureParameters.Copy());
				entireDatabase.Tables.Add(ProceduresHelper.Procedures.Copy());
				entireDatabase.Tables.Add(ProceduresHelper.Functions.Copy());
				entireDatabase.Tables.Add(ForeignKeysHelper.ForeignKeys.Copy());
				entireDatabase.Tables.Add(IndexColumnsHelper.IndexColumns.Copy());
				entireDatabase.Tables.Add(IndexesHelper.Indexes.Copy());
				entireDatabase.Tables.Add(UserDefinedTypesHelper.UserDefinedTypes.Copy());
				entireDatabase.Tables.Add(SMOHelper.TriggersHelper.Triggers.Copy());
				entireDatabase.Tables.Add(SMOHelper.UserDefinedDataTypesHelper.UserDefinedDataTypes.Copy());

				File.WriteAllText(fileName, entireDatabase.GetXml());
				MessageBox.Show("All data exported successfully to " + fileName);
		  }

		  /// <summary>
		  /// Removes the system DBS.
		  /// </summary>
		  private void RemoveSystemDBS()
		  {
				DataTable dbs = DatabasesHelper.Databases.Copy();
				foreach (DataRow dr in DatabasesHelper.Databases.Rows)
				{
					 DataRow[] rows =
						 dbs.Select(
							 "database_name = 'master' OR database_name = 'tempdb' OR database_name = 'model' OR database_name = 'msdb'");
					 foreach (DataRow r in rows)
						  r.Delete();
				}
				FillComboBox(ddlDatabase, dbs, "database_name", "dbid");
		  }
	 }
}